/**
 * XMLHTTPRequest对象
 * ajax是对它的封装
 * axios返回promise
 * fetch返回的是promise
 * JavaScript在发送AJAX请求时，URL的域名必须和当前页面完全一致（同源）
 */
const ajax = (method, url, data, isAsync=true) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
      if (xhr.readyState != 4) return;
      if (xhr.status == 200 || xhr == 304) { // 状态码是number， 304资源未被修改，客户端取缓存
        resolve(xhr.responseText);
      } else {
        reject(new Error(xhr.responseText));
      }
    };
    // xhr.setRequestHeader('Accept', 'application/json'); // 客户端期望接收的响应类型
    xhr.open(method, url, isAsync);
    xhr.send(data);
  });
};
/**
 * 详细版本
 */
function ajax(options) {
  return new Promise((resolve, reject)=>{
    const {url, method='GET', data={}, headers={}, isAsync=true}=options||{}
    
    method = method.toUpperCase();
    let queryStr = Object.keys(data).map(key=>key+'='+encodeURIComponent(data[key])).join('&')
    
    if(method==='GET'&& queryStr){
      url+=url.include('?') ? '&':'?' + queryStr
    }

    const xhr = new XMLHttpRequest();
    xhr.open(method, url, isAsync);
    // xhr.setRequestHeader('Content-Type', 'application-x-www-form-urlencoded')
    for(const key in headers) {
      xhr.setRequestHeader(key, headers[key])
    }
    xhr.onreadystatechange = function(){
      if(xhr.readystate===4) {
        if(xhr.status >= 200 && xhr.status < 300||xhr.status===304){
          try{
            const response = xhr.responseText
            resolve(JSON.parse(response))
          }catch(e){
            reject(JSON.parse(xhr.responseText))
          }
        }else{
          reject(new Error('请求失败'))
        }
      }
    }
    xhr.onerror = function(){
      reject(new Error('网络错误'))
    }
    xhr.ontimeout = function(){
      reject(new Error('请求超时'))
    }
    xhr.send(method=='GET'?null:queryStr)
  })
}
ajax({
  url: 'https://api.example.com/data',
  method: 'GET',
  data: { id: 1 }
})
  .then(response => console.log(response))
  .catch(error => console.error(error));